# Create your views here.
# -*- coding: utf-8 -*-

from django.views.generic.list_detail import object_list, object_detail
from wal.pedidos.models import Pedido, DetallePedido
from wal.pedidos.views import obtenerPedido, obtenerDetallePedido
from wal.expedicion.models import Expedicion, DetalleExpedicion
from wal.expedicion.forms import ExpedicionForm, DetalleExpedicionForm
from wal.pedidos.forms import SearchForm
from wal.control.models import Control, DetalleControl, Stock
from wal.articulos.models import Ensamblado, Partes
from django.template.context import RequestContext
from django.shortcuts import render_to_response
#from wal.views import update_object, create_object , delete_object
from django.views.generic.create_update import update_object, create_object , delete_object
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from wal.views import split_query_into_keywords
from django.db.models import Q

def obtenerExpedicion(request,object_id):
    if int(object_id):
        try:
            objectoExpedicion = Expedicion.objects.get(id=object_id)
        except ObjectDoesNotExist:
            return 'No existe el objecto'
    else:
        return 'No existe el objecto'
    return objectoExpedicion

def obtenerDetalleExpedicion(request,object_id):
    if int(object_id):
        try:
            objectoDetalle = DetalleExpedicion.objects.get(id=object_id)
        except ObjectDoesNotExist:
            return 'No existe el objecto'
    else:
        return 'No existe el objecto'
    return objectoDetalle

def search_for_keywords(keywords):
    """Make a search that contains all of the keywords."""
    expediciones = Expedicion.objects.all()
    for keyword in keywords:
        expediciones = expediciones.filter(nombre__icontains=keyword)
    return expediciones

def listar(request,object_id,ot,o,page):
    
    pedido = obtenerPedido(request, object_id)
    if pedido == 'No existe el objecto':
        return render_to_response('error.html',{'error':'No existe el objecto'})
    
    request.breadcrumbs([('Pedidos','/wal/pedidos/listar/ot=asc&o=3&page=1'),(pedido.nombre,'/wal/pedidos/ver/'+str(pedido.id)),('Expediciones',request.path)])
    
    if ot=='asc':
        if int(o) == 1:
            orden = "-nombre"
        elif int(o) == 2:
            orden = "-fecha"
        elif int(o) == 3:
            orden = "-factura"
        elif int(o) == 4:
            orden = "-remision"
        elif int(o) == 5:
            orden = "-responsable"
        else:
            orden = "-nombre"
    elif ot=='desc':
        if int(o) == 1:
            orden = "nombre"
        elif int(o) == 2:
            orden = "fecha"
        elif int(o) == 3:
            orden = "factura"
        elif int(o) == 4:
            orden = "remision"
        elif int(o) == 4:
            orden = "responsable"
        else:
            orden = "nombre"
    else:
        orden = "-nombre"
    if request.method == 'GET':
        form = SearchForm(request.GET)
        if form.is_valid():
            keywords = form.cleaned_data['keywords']
            keyword_list = split_query_into_keywords(keywords)
            expediciones = search_for_keywords(keyword_list)
            if expediciones:
                # Show the results
                qs = expediciones.order_by(orden)
            else:
                qs = Expedicion.objects.none()
            form = SearchForm()
            return object_list(request,
                   queryset = qs,
                   allow_empty = True,
                   template_name = 'expedicion/listar.html',
                   extra_context = {'ot':ot,'o':o,'page':page,'form':form},
                   paginate_by = 20,
                   page = page,
                   )
    else:
        form = SearchForm()
    return object_list(request,
                       queryset = Expedicion.objects.filter(pedido=object_id).order_by(orden),
                       allow_empty = True,
                       template_name = 'expedicion/listar.html',
                       extra_context = {'pedido': object_id,'ot':ot,'o':o,'page':page,'form':form},
                       paginate_by = 20,
                       page = page,
                       )
#    return object_list(request,
#                       queryset = Expedicion.objects.filter(pedido=object_id).order_by("-fecha"),
#                       allow_empty = True,
#                       template_name = 'expedicion/listar.html'
#                       )
    
def ver(request, object_id):
    expedicion = obtenerExpedicion(request, object_id)
    if expedicion == 'No existe el objecto':
        return render_to_response('error.html',{'error':'No existe el objecto'})
    el_pedido = expedicion.pedido
    
    request.breadcrumbs([('Pedidos','/wal/pedidos/listar/ot=asc&o=3&page=1'),(el_pedido.nombre,'/wal/pedidos/ver/'+str(el_pedido.id)),('Expediciones',reverse(listar,args=[el_pedido.id,'asc',1,1])),(expedicion.nombre,request.path)])
    
    if request.method == "POST":
        cforms = DetalleExpedicionForm(el_pedido,request.POST, instance=DetalleExpedicion())
        
        #controlar la cantidad expedida
        
        if cforms.is_valid():
            new_detalle = cforms.save(commit=False)
            new_detalle.proceso = el_pedido.proceso
            
            art = new_detalle.articulo
            ens = Ensamblado.objects.filter(nombre=art.nombre)
            
            if ens:
                ens = Ensamblado.objects.get(nombre=art.nombre)
                partes = Partes.objects.filter(ensamblado=ens)
                check = CheckStock(el_pedido,new_detalle.articulo,new_detalle.proceso,new_detalle.cantidad)
                if check:
                    for p in partes:
                        c = p.cantidad*new_detalle.cantidad
                        peso = 0
                        stock = Stock.objects.get(pedido=el_pedido,articulo=p.articulo,proceso=new_detalle.proceso)
                        
                        peso = c*stock.peso
                        stock.stock = stock.stock - c
                        stock.despachado = stock.despachado + c
                        stock.save()
                        new_det = DetalleExpedicion.objects.filter(expedicion=expedicion,articulo=p.articulo,proceso=new_detalle.proceso)
                        if new_det:
                            new_det = DetalleExpedicion.objects.get(expedicion=expedicion,articulo=p.articulo,proceso=new_detalle.proceso)
                            new_det.cantidad = new_det.cantidad + c
                            new_det.peso = new_det.peso + peso
                        else:
                            new_det = DetalleExpedicion(expedicion=expedicion,articulo=p.articulo,cantidad=c,proceso=new_detalle.proceso,peso=peso,receptor=new_detalle.receptor)
                        new_det.save()
                    return HttpResponseRedirect(reverse(ver, args=[object_id]))
                else:
                    cleaned_data = super(DetalleExpedicionForm, cforms).clean()
                    cant = cleaned_data.get("cantidad")
                    #raise forms.ValidationError("Las Fechas están mal!")
                    msg = u"La Cantidad está mal!"
                    cforms._errors["cantidad"] = cforms.error_class([msg])
            
                    # These fields are no longer valid. Remove them from the
                    # cleaned data.
                    del cleaned_data["cantidad"]
            else:
                stock = Stock.objects.filter(pedido=el_pedido,articulo=new_detalle.articulo,proceso=new_detalle.proceso)
                peso = 0
                
                cleaned_data = super(DetalleExpedicionForm, cforms).clean()
                cant = cleaned_data.get("cantidad")
                
                if stock:
                    stock = Stock.objects.get(pedido=el_pedido,articulo=new_detalle.articulo,proceso=new_detalle.proceso)
                    scant = stock.stock
                else:
                    scant = 0
                if cant > scant:
                    #raise forms.ValidationError("Las Fechas están mal!")
                    msg = u"La Cantidad está mal!"
                    cforms._errors["cantidad"] = cforms.error_class([msg])
            
                    # These fields are no longer valid. Remove them from the
                    # cleaned data.
                    del cleaned_data["cantidad"]
                else:
                    peso = cant*stock.peso
                    stock.stock = scant - cant
                    stock.despachado = stock.despachado + cant
                    stock.save()
                    new_det = DetalleExpedicion.objects.filter(expedicion=expedicion,articulo=new_detalle.articulo,proceso=new_detalle.proceso)
                    if new_det:
                        new_det = DetalleExpedicion.objects.get(expedicion=expedicion,articulo=new_detalle.articulo,proceso=new_detalle.proceso)
                        new_det.cantidad = new_det.cantidad + cant
                        new_det.peso = new_det.peso + peso
                        new_det.save()
                    else:
                        new_detalle.expedicion = expedicion
                        new_detalle.peso = peso
                        new_detalle.save()
                    return HttpResponseRedirect(reverse(ver, args=[object_id]))
    else:
        cforms = DetalleExpedicionForm(el_pedido,instance=DetalleExpedicion())
    detalle = DetalleExpedicion.objects.filter(expedicion=object_id)
    list = []
    ptotal=0
    for item in detalle:
        list.append(item)
        ptotal = ptotal + item.peso
    return render_to_response('expedicion/detalles.html', {'expedicion': expedicion, 'detalle': list, 'detalle_forms': cforms, 'pedido': el_pedido, 'ptotal': ptotal}, context_instance=RequestContext(request))

def CheckStock(pedido,articulo,proceso,cantidad):
    ens = Ensamblado.objects.get(nombre=articulo.nombre)
    partes = Partes.objects.filter(ensamblado=ens)
    for p in partes:
        c = p.cantidad*cantidad
        stock = Stock.objects.filter(pedido=pedido,articulo=p.articulo,proceso=proceso)
        if stock:
            stock = Stock.objects.get(pedido=pedido,articulo=p.articulo,proceso=proceso)
            scant = stock.stock
        else:
            scant = 0
        if cantidad > scant:
            return False
    return True
def crear(request,object_id):
    pedido = obtenerPedido(request, object_id)
    if pedido == 'No existe el objecto':
        return render_to_response('error.html',{'error':'No existe el objecto'})
    
    request.breadcrumbs([('Pedidos','/wal/pedidos/listar/ot=asc&o=3&page=1'),(pedido.nombre,'/wal/pedidos/ver/'+str(pedido.id)),('Expediciones',reverse(listar,args=[pedido.id,'asc',1,1])),('Crear Expedición',request.path)])
    
    if request.method == "POST":
        pform = ExpedicionForm(request.POST, instance=Expedicion())
        if pform.is_valid():
            new_expedicion = pform.save(commit=False)
            new_expedicion.pedido = pedido
            new_expedicion.cliente = pedido.cliente
            
            cleaned_data = super(ExpedicionForm, pform).clean()
            fecha = cleaned_data.get("fecha")
            pfecha = pedido.fecha
            pplazo = pedido.plazo
            if fecha < pfecha or fecha > pplazo:
                #raise forms.ValidationError("Las Fechas están mal!")
                msg = u"La Fecha está mal!"
                pform._errors["fecha"] = pform.error_class([msg])
        
                # These fields are no longer valid. Remove them from the
                # cleaned data.
                del cleaned_data["fecha"]
            else:
                new_expedicion.save()
                return HttpResponseRedirect(reverse(ver, args=[new_expedicion.id]))
    else:
        pform = ExpedicionForm(instance=Expedicion())
    return render_to_response('expedicion/expedicion.html', {'form': pform,'pedido':object_id}, context_instance=RequestContext(request))

def editar(request, object_id):
    expedicion = obtenerExpedicion(request, object_id)
    if expedicion == 'No existe el objecto':
        return render_to_response('error.html',{'error':'No existe el objecto'})

    pedido = expedicion.pedido

    request.breadcrumbs([('Pedidos','/wal/pedidos/listar/ot=asc&o=3&page=1'),(pedido.nombre,'/wal/pedidos/ver/'+str(pedido.id)),('Expediciones',reverse(listar,args=[pedido.id,'asc',1,1])),('Editar '+expedicion.nombre,request.path)])

    return update_object(request,
                        model = Expedicion, 
                        #form_class = PedidosForm,
                        template_name = 'expedicion/expedicion.html', 
                        post_save_redirect = reverse(ver,args=[object_id]),
                        object_id = object_id,
                        form_class = ExpedicionForm
                        )
    
def borrar(request, object_id,ot,o,page):
    expedicion = obtenerExpedicion(request, object_id)
    if expedicion == 'No existe el objecto':
        return render_to_response('error.html',{'error':'No existe el objecto'})
    pedido = expedicion.pedido
    if request.method == "POST":
        detalles = DetalleExpedicion.objects.filter(expedicion=expedicion)
        for det in detalles:
            stock = Stock.objects.filter(pedido=pedido,articulo=det.articulo,proceso=det.proceso)
            if stock:
                st = Stock.objects.get(pedido=pedido,articulo=det.articulo,proceso=det.proceso)
                st.stock = st.stock + det.cantidad
                st.despachado = st.despachado - det.cantidad
                st.save()
    return delete_object(request,
                         model = Expedicion, 
                         template_name = 'expedicion/confirm_delete_expedicion.html', 
                         post_delete_redirect = reverse(listar, args=[pedido.id,ot,o,page]),
                         object_id = object_id
                         )
    
def borrarDetalle(request, object_id):
    detalle = obtenerDetalleExpedicion(request, object_id)
    if detalle == 'No existe el objecto':
        return render_to_response('error.html',{'error':'No existe el objecto'})
    expedicion = detalle.expedicion
    pedido = expedicion.pedido
    if request.method == "POST":
        stock = Stock.objects.filter(pedido=pedido,articulo=detalle.articulo,proceso=detalle.proceso)
        if stock:
            st = Stock.objects.get(pedido=pedido,articulo=detalle.articulo,proceso=detalle.proceso)
            st.stock = st.stock + detalle.cantidad
            st.despachado = st.despachado - detalle.cantidad
            st.save()
    return delete_object(request,
                         model = DetalleExpedicion, 
                         template_name = 'expedicion/confirm_delete_detalle.html', 
                         post_delete_redirect = reverse(ver, args=[expedicion.id]),
                         object_id = object_id
                         )